package com.storlead.email.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.storlead.email.service.EmailService;

import com.storlead.email.util.EmailUtils;
import com.sun.mail.imap.IMAPStore;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @Author: Timo
 * @Date: 2019/2/11 15:07
 * @Description: 类用途：
 * <p>
 * demo 1 : http://www.zhaoguojian.com/2018/06/15/%E5%9F%BA%E4%BA%8ESpringBoot%E5%AE%9E%E7%8E%B0%E9%82%AE%E4%BB%B6%E6%94%B6%E5%8F%91%E5%88%A0%E9%99%A4/
 */
@Slf4j
@Service
public class EmailServiceImpl implements EmailService {

    @Value("${emailAccount}")
    private String emailAccount;

    @Qualifier("javaMailSenderQQ")
    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private TemplateEngine templateEngine;

    private MailSender mailSenders;
    private SimpleMailMessage templateMessage;

    @Override
    public void sendEmail(String toEmail, String subject, String content) {
        sendEmail(toEmail, subject, content, null, false);

    }

    @Override
    public void sendEmail(String toEmail, String subject, String content, Map<String, File> fileUrls, boolean html) {
        try {
            MimeMessage message = getMimeMessage();
            message.getMessageID();
            setMimeMessageHelper(message, toEmail, subject, content, fileUrls, false);
            sendEmail(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void sendHtmlEmail(String toEmail, String subject, String content) {

    }

    @Override
    public void sendHtmlEmail(String toEmail, String subject, String content, Map<String, File> fileUrls) {
        // 设置模板中需要替换得变量
        Context htmlContext = new Context();
        htmlContext.setVariable("welcome", "welcome");
        htmlContext.setVariable("name", "timo");
        htmlContext.setVariable("id", "1668");

        // 根据模板 替换模板中的变量
        String emailContent = templateEngine.process("emailTemplate", htmlContext);
        // 发送邮件
        sendEmail(toEmail, subject, emailContent, fileUrls, true);
    }

    private MimeMessageHelper getMimeMessageHelper(MimeMessage mimeMessage) throws MessagingException {
        return new MimeMessageHelper(mimeMessage, true);
    }

    private MimeMessageHelper setMimeMessageHelper(MimeMessage mimeMessage, String toEmail, String subject, String content, boolean html) throws MessagingException {
        return setMimeMessageHelper(mimeMessage, toEmail, subject, content, null, html);
    }


    /**
     * 设置发送邮件的助手
     *
     * @param mimeMessage 消息
     * @param toEmail     接收者
     * @param subject     主题
     * @param content     内容
     * @param fileObj     文件
     * @param html        是否是html 格式  true（html） /  文本格式（flase）
     * @return
     * @throws MessagingException
     */
    private MimeMessageHelper setMimeMessageHelper(MimeMessage mimeMessage, String toEmail, String subject, String content, Map<String, File> fileObj, boolean html) throws MessagingException {
        MimeMessageHelper helper = getMimeMessageHelper(mimeMessage);
        helper.setFrom(emailAccount);
        helper.setTo(toEmail);
        helper.setSubject(subject);
        System.out.println(content);
        helper.setText(content, html);
        helper.setSentDate(new Date());
        if (fileObj != null && fileObj.size() > 0) {
            for (String key : fileObj.keySet()) {
                helper.addAttachment(key, fileObj.get(key));
            }
        }
        return helper;
    }

    /**
     * 获取消息主体
     *
     * @return
     */
    private MimeMessage getMimeMessage() {
        return javaMailSender.createMimeMessage();
    }


    /**
     * 发送邮件消息
     *
     * @param mimeMessage
     */
    private void sendEmail(MimeMessage mimeMessage) {
        javaMailSender.send(mimeMessage);
    }


    @Override
    public JSONObject receivEmail(String emailType) {
        try {
            resceive(emailType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private void resceive(String emailType) throws Exception {
        // 设置环境变量
        Properties props = System.getProperties();
        EmailServiceEnum serviceEnum = EmailServiceEnum.getEmailServiceEnum(emailType);
        if (serviceEnum != null){
            serviceEnum.serviceData.forEach((k,v) ->{
                log.info("k:{}, v:{}",k,v);
                props.setProperty(k, v);
            });
        }

        URLName urln = null;
        EmailAccountEnum accountEnum = EmailAccountEnum.getEmailAccountEnum(emailType);
        if (accountEnum != null){
            urln = accountEnum.urlName;
            log.info("{}",urln);
        }

        Session session = Session.getInstance(props);
        Store store = session.getStore(urln);
        store.connect();


        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_WRITE);
        System.out.println("未读邮件数量：" + folder.getUnreadMessageCount());
        System.out.println("新邮件 数 量：" + folder.getNewMessageCount());
        System.out.println("邮件总 数 量：" + folder.getMessageCount());
        parseMessage(folder.getMessages());

    }

    public enum EmailServiceEnum {
        exmail_qq("exmail_qq", ImmutableMap.of(
                "mail.store.protocol", "imap",
                "mail.smtp.host", "smtp.exmail.qq.com",
                "mail.smtp.port", "143",
                "mail.smtp.auth", "true")),

        qq("qq", ImmutableMap.of(
                "mail.store.protocol", "imap",
                "mail.imap.host", "imap.qq.com",
                "mail.smtp.port", "143",
                "mail.smtp.auth", "true"));

        public String emaliType;
        public Map<String, String> serviceData;



        EmailServiceEnum(String emaliType, Map<String, String> serviceData) {
            this.emaliType = emaliType;
            this.serviceData = serviceData;
        }

        public static EmailServiceEnum getEmailServiceEnum(String emailType){
            for (EmailServiceEnum serviceEnum : EmailServiceEnum.values()){
                if (serviceEnum.emaliType.equals(emailType)){
                    return serviceEnum;
                }
            }
            return null;
        }

    }

    public enum EmailAccountEnum {

        exmail_qq("exmail_qq", new URLName("imap", "smtp.exmail.qq.com", 143, null, "timo@storlead.com", "Jyx19910320.")),
        qq("qq", new URLName("imap", "imap.qq.com", 143, null, "1002512666@qq.com", "gshjwpkyfwkgbddg"));

        public String emailType;
        public URLName urlName;

        EmailAccountEnum(String emailType, URLName urlName) {
            this.emailType = emailType;
            this.urlName = urlName;
        }

        public static EmailAccountEnum getEmailAccountEnum(String emailType){
            for (EmailAccountEnum account : EmailAccountEnum.values()){
                if (account.emailType.equals(emailType)){
                    return account;
                }

            }
            return null;
        }
    }

    private void parseMessage(Message... messages) throws Exception {
        if (messages == null || messages.length < 1) {
            throw new MessagingException("not find email");
        }


        for (Message message : messages) {
            MimeMessage msg = (MimeMessage) message;
            System.out.println("------------------解析第" + msg.getMessageNumber() + "封邮件-------------------- ");
            System.out.println("主题: " + msg.getSubject());
            System.out.println("发件人名称: " + EmailUtils.getFrom(msg)[0]);
            System.out.println("发件人邮箱: " + EmailUtils.getFrom(msg)[1]);
            System.out.println("收件人：" + EmailUtils.getReceiveAddress(msg, null));
            System.out.println("发送时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(msg.getSentDate()));
            System.out.println("是否已读：" + msg.getFlags().contains(Flags.Flag.SEEN));
            System.out.println("邮件优先级：" + EmailUtils.getPriority(msg));
            System.out.println("是否需要回执：" + (msg.getHeader("Disposition-Notification-To") != null ? true : false));
            System.out.println("邮件大小：" + msg.getSize() * 1024 + "kb");
            StringBuffer content = new StringBuffer(100);
            EmailUtils.getMailTextContent(msg, content);
            System.out.println("邮件正文：" + content);

            boolean isContainerAttachment = EmailUtils.isContainAttachment(msg);
            System.out.println("是否包含附件：" + isContainerAttachment);


            System.out.println("------------------第" + msg.getMessageNumber() + "封邮件解析结束-------------------- ");
            System.out.println();
        }

    }

}
